﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud
using System.Runtime.Serialization;
using System;
using System.Xml.Serialization;
using System.Threading;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BrainTechLLC.ThreadSafeObjects;

namespace BrainTechLLC
{
    public class ListCommand : Command, ICommandInfo
    {
        public override string HelpText { get { return "Lists all things given a list of types, or list things by keyword"; } }
        public override string Example { get { return "(1) list TYPE:GameChar, (2) list joe green"; } }

        [NonSerialized, XmlIgnore]
        public static List<string> Words = new List<string>() { "LIST" };

        public override List<string> FirstWords { get { return Words; } }

        public override CommandToPerform CreateCommand(IGameThing source, string first, string input)
        {
            CommandToPerform cmd = new CommandToPerform()
            {
                ApplyToID = source.AssociatedID,
                Arguments = new PropertyData(new IdentifierAndValue() { Identifier = "ListParameters", Value = input }),
                PerformMethod = new Method("ListCommand", "PerformListCommand")
            };
            return cmd;
        }

        public override bool CheckIsValid(IGameThing source, string first, string input)
        {
            return true;
        }

        [MethodVisible]
        public static List<PerceivedEventAndAudience> PerformListCommand(CommandToPerform cmd, IGameThing source, IGameThing target, PropertyData args, PropertyData modifyingArguments)
        {
            List<PerceivedEventAndAudience> events = new List<PerceivedEventAndAudience>();
            GameThingBaseClass hasName = source as GameThingBaseClass;
            ICanBeNotified notify = source as ICanBeNotified;
            string lookParams = args.GetArgument<string>("ListParameters", string.Empty);

            if (hasName != null)
            {
                string[] strings = lookParams.Split(" ".ToCharArray(), 2, StringSplitOptions.None);
                EventToPerceive evt = new EventToPerceive()
                {
                    Sources = new AssociatedIDCollection(notify.AssociatedID)
                };

                if (strings.Length > 0)
                {
                    List<Type> types = new List<Type>();
                    string first;
                    while (" ".StripNextWord(ref strings[0], out first))
                    {
                        string stringType = StringTypes.DetermineStringType(ref first);
                        if (stringType == "TYPE")
                        {
                            Type t = TypeProvider.GetInstance().GetType(first);
                            
                            if (t != null)
                                types.Add(t);
                        }
                        else
                        {
                            strings[0] = first + " " + strings[0];
                            break;
                        }
                    }
                    List<MatchAndStrength> matchedItems = null;
                    float f = strings[0].Find<IGameThing>(ref matchedItems, 0, types.ToArray());
                    if (matchedItems != null)
                    {
                        evt._event = new Event(matchedItems.BuildList(Environment.NewLine, (v) => String.Format("{0} - {1} - {2} - {3}", f, v.MatchMeasure, v.MatchString, v.MatchedItem.ToString())), ViewType.See);
                        events.Add(new PerceivedEventAndAudience() { Audience = new AssociatedIDCollection(notify.AssociatedID), Event = evt });
                    }
                }
            }

            return events;
        }
    }
}
